<?php

namespace app\trait;

use app\constant\CommonConstant;
use app\constant\ModelConstant;
use app\exception\PushShopifyOrderException;
use app\exception\QueueRuntimeException;
use app\model\LineItems;
use app\model\Notify;
use app\model\Orders;
use app\model\ShopsPayment;
use app\service\shopify\action\graph\CartGraph;
use app\service\shopify\action\graph\OrderGraph;
use app\service\shopify\action\rest\DraftOrderRest;
use app\service\shopify\action\rest\OrderRest;
use think\exception\ValidateException;
use think\helper\Arr;
use think\Request;

trait ShopifyTrait
{
    public function formatDraftItems(array $lineItems, string $currencyCode): array
    {
        return array_map(function ($item) use ($currencyCode) {
            $variantId = '';
            if (Arr::exists($item, 'variant_id') && Arr::get($item, 'variant_id')) {
                $variantId = sprintf("gid://shopify/ProductVariant/%s", Arr::get($item, 'variant_id'));
            }
            $line = [
                "priceOverride" => [
                    "amount" => Arr::get($item, "price"),
                    "currencyCode" => $currencyCode
                ],
                "quantity" => Arr::get($item, "quantity", 1),
                "customAttributes" => [
                    [
                        'key' => 'sku',
                        'value' => Arr::get($item, 'sku','') ?: strval(Arr::get($item, 'variant_id'))
                    ]
                ],
            ];
            if ($variantId) {
                $line['variantId'] = $variantId;
                $line['components'] = [
                    "quantity" => Arr::get($item, "quantity", 1),
                    'variantId' => $variantId
                ];
            }
            return $line;
        }, $lineItems);
    }

    protected function saveDraftResult(Orders $order, array $draftResult, string $key = "draftOrderCreate")
    {
        $draftKey = sprintf('data.%s.draftOrder', $key);
        $draft = Arr::get($draftResult, $draftKey, []);
        if (empty($draft)) return $draft;
        $order->draft_id = Arr::get($draft, 'id');
        $order->name = Arr::get($draft, 'name');
        $order->draft_status = Arr::get($draft, 'status');
        $order->shop_currency = Arr::get($draft, 'currencyCode', 'USD');
        //小计
        $order->subtotal_present = Arr::get($draft, 'subtotalPriceSet.presentmentMoney.amount');
        $order->subtotal_shop = Arr::get($draft, 'subtotalPriceSet.shopMoney.amount');
        //总计
        $order->total_present = Arr::get($draft, 'totalPriceSet.presentmentMoney.amount');
        $order->total_shop = Arr::get($draft, 'totalPriceSet.shopMoney.amount');
        //优惠
        $order->discount_present = Arr::get($draft, 'totalDiscountsSet.presentmentMoney.amount');
        $order->discount_shop = Arr::get($draft, 'totalDiscountsSet.shopMoney.amount');
        //运费
        $order->shipping_price_present = Arr::get($draft, 'totalShippingPriceSet.presentmentMoney.amount');
        $order->shipping_price_shop = Arr::get($draft, 'totalShippingPriceSet.shopMoney.amount');
        //税费
        $order->tax_present = Arr::get($draft, 'totalTaxSet.shopMoney.amount');
        $order->tax_shop = Arr::get($draft, 'totalTaxSet.shopMoney.amount');
        $order->shopify_order_id = Arr::get($draft, 'order.id', '');
        $order->utc_at = Arr::get($draft, 'completedAt', '');
        $orderStatusUrl = Arr::get($draft, 'order.statusPageUrl', '');
        $order->order_status_url = $orderStatusUrl;
        $order->last_order_name = Arr::get($draft, 'order.name', '');
        if ($orderStatusUrl) $order->is_completed = ModelConstant::STATUS_ON;
        $order->save();
        return $draft;
    }

    //获取订单成功页面
    public function getOrderSuccessUrl(Orders $order)
    {
        try {
            $order = $order->is_repurchase ? $order->parent : $order;
            if ($order->order_status_url) return $order->order_status_url;
            $rest = new OrderGraph($order->shop_id, true);
            if ($order->shopify_order_id) {
                $result = $rest->retrieve_a_specific_order($order->shopify_order_id);
                return Arr::get($result, 'data.order.statusPageUrl', '');
            }
            $draftInfo = $rest->retrieve_a_draft_order($order->draft_id);
            $orderStatusUrl = Arr::get($draftInfo, 'data.draftOrder.order.statusPageUrl', '');
            if ($orderStatusUrl) return $orderStatusUrl;
            $completeResult = $this->completedDraftOrder($order);
            $draft = Arr::get($completeResult, 'data.draftOrderComplete.draftOrder', []);
            return Arr::get($draft, 'order.statusPageUrl', '');
        }catch (\Exception $e){
            return  '';
        }
    }

    public function completedDraftOrder(Orders $order, bool $debug = false)
    {
        if ($order->isEmpty()) throw new QueueRuntimeException('订单不存在');
        if ($debug) echo '***********正在执行订单ID: ' . $order->id . '**********'.PHP_EOL;
        if ($order->order_status != Orders::ORDER_STATUS_COMPLETED) throw new QueueRuntimeException('订单未支付');
        if ($order->is_completed) throw new QueueRuntimeException('订单已处理');
        $draftApi = new OrderGraph($order->shop_id, true);
        //仅更新一次,避免重复调接口
        if(!$order->is_updated){
            $firstPurchase = $order->purchases()
                ->where('order_status', Orders::ORDER_STATUS_COMPLETED)
                ->findOrEmpty();
            $tags = [];
            if($order->trade_no) $tags[] = $order->trade_no;
            $updateDraft = [];
            if (!$firstPurchase->isEmpty()) {
                $lineItems = LineItems::query()
                    ->whereIn('order_id', [$order->id, $firstPurchase->id])
                    ->field(['price', 'variant_id', 'quantity', 'sku'])
                    ->select()
                    ->toArray();
                $lineItems = $this->formatDraftItems($lineItems, $order->present_currency);
                $updateDraft['lineItems'] = $lineItems;
                $tags[] = $firstPurchase->trade_no;
            }
            if($order->paypal_method == Orders::PAYPAL_METHOD_GOOGLE) $tags[] = 'GooglePay';
            if($order->paypal_method == Orders::PAYPAL_METHOD_APPLE) $tags[] = 'ApplePay';
            $tag = $order->pay_method == ShopsPayment::PAY_METHOD_PAYPAL ? "PP" :'Card';
            $tags[] = $tag;
            $updateDraft['tags'] = $tags;
            if ($order->is_paypal_kj) {
                $updateDraft['email'] = $order->email;
                $updateDraft['shippingAddress'] = [
                    "address1" => $order->shippingAddress->address1,
                    "city" => $order->shippingAddress->city,
                    "province" => $order->shippingAddress->province,
                    "country" => $order->shippingAddress->country,
                    "zip" => $order->shippingAddress->zip
                ];
            }
            tplog("/updateDraft/params/{$order->id}",['params' => $updateDraft],'shopify');
            $updateResult = $draftApi->update_draft_order($order->draft_id, $updateDraft);//更新订单
            Notify::saveParams($order->id, ['params' => $updateDraft, 'response' => $updateResult,], Notify::TYPE_UPDATE_ORDER, $order->pay_method);//创建草稿订单
            tplog("/updateDraft/result/{$order->id}",['response' => $updateResult],'shopify');
            $updateErrors = Arr::get($updateResult, 'data.draftOrderUpdate.userErrors', []);
            if(empty($updateErrors)){
                $order->is_updated = ModelConstant::STATUS_ON;
                $order->save();
            }
        }
         sleep(2);//完成订单之前睡3s
        $completeResult = $draftApi->complete_draft_order($order->draft_id);//保存结果
        $userErrors = Arr::get($completeResult, 'data.draftOrderComplete.userErrors', []);
        tplog("/completeDraft/result/{$order->id}",['response' => $completeResult],'shopify');
        $this->saveDraftResult($order, $completeResult, 'draftOrderComplete');
        Notify::saveParams($order->id, ['params' => $order->draft_id,  'response' => $completeResult], Notify::TYPE_COMPLETE_DRAFT, $order->pay_method);//创建草稿订单
        if ($userErrors && $debug) throw new PushShopifyOrderException(implode(',', array_column($userErrors, 'message')));
        return $completeResult;
    }

    protected function createCheckoutId(Request $request)
    {
        $checkout = $request->post('checkout',[]);
        $cart = Arr::get($checkout,'cart',[]);
        $lineItems = Arr::get($cart,'items',[]);
        if(empty($lineItems)) throw new ValidateException("cart must not empty");
        $lines = [];
        foreach ($lineItems as $item){
            if(!isset($item['variant_id']) || empty($item['variant_id'])) throw new ValidateException('variantId require');
            if(!isset($item['quantity']) || empty($item['quantity'])) throw new ValidateException('quantity require');
            if(in_array($item['product_title'],CommonConstant::SHIPPING_PROTECTION_FEE)) continue;
            $lines[] = [
                "attributes"=>[
                    ["key"=>"id","value"=>strval(Arr::get($item,'id'))],
                ],
                'merchandiseId'=>sprintf('gid://shopify/ProductVariant/%s',$item['variant_id']),
                'quantity'=>$item['quantity'],
            ];
        }
        $currency = Arr::get($cart,'currency','USD');
        $cartInput = [
            'attributes'=>[
                ['key'=>"token","value"=>Arr::get($cart,'token','')],
                ['key'=>"currency","value"=>$currency],
            ],
            'discountCodes'=>Arr::get($cart,"discountCodes",[]),
            'giftCardCodes'=>["test"],
            'lines'=>$lines,
            'metafields'=>[
                [
                    'type'=>"money",
                    'key'=>'total_price',
                    'value'=>json_encode(['amount'=>Arr::get($cart,'total_price',0),'currency_code'=>"USD"])
                ]
            ],
        ];

        $store = new CartGraph($request->x_shop_id);
        $data = $store->createCart($cartInput);
        $errors = Arr::get($data,'errors',[]);
        if($errors){
            $message = array_column($errors,'message');
            throw new \Exception(implode(',',$message));
        }
        $errors = Arr::get($data,'data.cartCreate.userErrors',[]);
        if($errors){
            $message = array_column($errors,'message');
            throw new \Exception(implode(',',$message));
        }
        $checkoutUrl = Arr::get($data,'data.cartCreate.cart.checkoutUrl','');
        $checkoutId = pathinfo($checkoutUrl,PATHINFO_BASENAME);
        return  Arr::first(explode('?',$checkoutId));
    }



}